﻿using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using System.Xml.Serialization;

namespace ZLB_Unility.Common
{
    public class JsonXmlUtils
    {
        #region Xml和Json互转
        public static string XmlToJson(string xml)
        {
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);

            string jsonContent = JsonConvert.SerializeXmlNode(doc);
            return jsonContent;
        }

        public static string JsonToXml(string json)
        {
            XmlDocument doc = JsonConvert.DeserializeXmlNode(json);
            string result = ConvertXmlToString(doc);
            return result;
        }

        public static string ConvertXmlToString(XmlDocument xmlDoc)
        {
            MemoryStream stream = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(stream, null);
            writer.Formatting = System.Xml.Formatting.Indented;
            xmlDoc.Save(writer);
            StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
            stream.Position = 0;
            string xmlString = sr.ReadToEnd();
            sr.Close();
            stream.Close();
            return xmlString;
        }
        #endregion

        #region Xml和实体类互转
        /// <summary>
        /// 默认去除xml
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        /// <param name="isStatement"></param>
        /// <returns></returns>
        public static string XmlSerialize<T>(T obj, bool isStatement = true)
        {
            StringWriter sw = new StringWriter();

            Type t = obj.GetType();
            XmlSerializer serializer = new XmlSerializer(obj.GetType());
            if (isStatement)
            {
                XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
                ns.Add(string.Empty, string.Empty);
                serializer.Serialize(sw, obj, ns);
            }
            else
                serializer.Serialize(sw, obj);

            sw.Close();
            string xml = sw.ToString();

            if (isStatement)
            {
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(xml);
                xml = xmlDoc.DocumentElement.OuterXml;
            }

            return xml;
        }

        //public static string XmlSerialize<T>(T obj)
        //{
        //    string xmlString = string.Empty;

        //    Encoding encoding = Encoding.UTF8;
        //    using (MemoryStream memoryStream = new MemoryStream())
        //    {
        //        XmlSerializer xmlSerializer = new XmlSerializer(obj.GetType());
        //        XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
        //        namespaces.Add(string.Empty, string.Empty);

        //        // 去除<? ?>
        //        XmlWriterSettings settings = new XmlWriterSettings();
        //        settings.OmitXmlDeclaration = true;//这一句表示忽略xml声明
        //        settings.Indent = false;
        //        settings.Encoding = encoding;

        //        XmlWriter tw = XmlWriter.Create(memoryStream, settings);
        //        xmlSerializer.Serialize(tw, obj, namespaces);
        //        xmlString = encoding.GetString(memoryStream.ToArray());
        //        tw.Flush();
        //        tw.Close();
        //    }
        //    return xmlString;
        //}

        public static T DESerializer<T>(string strXML) where T : class
        {
            try
            {
                using (StringReader sr = new StringReader(strXML))
                {
                    XmlSerializer serializer = new XmlSerializer(typeof(T));
                    return serializer.Deserialize(sr) as T;
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return null;
            }
        }

        public static T DeserializeXML<T>(string xml) where T : class, new()
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(xml);
            T t = new T();
            PropertyInfo[] props = t.GetType().GetProperties();
            foreach (PropertyInfo p in props)
            {
                string root = "xml";
                if (xmlDoc.LastChild != null && !string.IsNullOrEmpty(xmlDoc.LastChild.LocalName))
                    root = xmlDoc.LastChild.LocalName;
                XmlNode xmlNode = xmlDoc.SelectSingleNode($"{root}/{ p.Name}");
                string pVal = string.Empty;
                if (xmlNode != null)
                    pVal = xmlNode.InnerText;

                if (p.PropertyType == typeof(Int32))
                    p.SetValue(t, int.Parse(pVal));
                else if (p.PropertyType == typeof(DateTime))
                    p.SetValue(t, DateTime.Parse(pVal));
                else if (p.PropertyType == typeof(Guid))
                    p.SetValue(t, Guid.Parse(pVal));
                else if (p.PropertyType == typeof(Int64))
                    p.SetValue(t, long.Parse(pVal));
                else
                    p.SetValue(t, pVal);
            }

            return t;
        }
        #endregion

        #region Json和实体互转
        public static string SerializeObject(object obj)
        {
            return JsonConvert.SerializeObject(obj);
        }

        public static T DeserializeObject<T>(string content)
        {
            return JsonConvert.DeserializeObject<T>(content);
        }
        #endregion
    }
}
